﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MIPS_Simulator
{
    class ALU
    {
        private long read1;
        public long Read1
        {
            get
            {
                return read1;
            }
            set
            {
                read1 = value;
            }
        }

        private long read2;
        public long Read2
        {
            get
            {
                return read2;
            }
            set
            {
                read2 = value;
            }
        }

        private bool zero;
        public bool Zero
        {
            get
            {
                return zero;
            }
        }
        private int control;
        public int Control
        {
            get
            {
                return control;
            }
            set
            {
                control = value;
            }
        }
        private long result;
        public long Result
        {
            get
            {
                return result;
            }
            set
            {
                result = value;
            }
        }

        public ALU()
        {
            read1 = 0;
            read2 = 0;
            control = 0;
            zero = false;
            result = 0;
        }

        public void Calculate()
        {
            switch (control)
            {
                case 1: result = read1 & read2;  break; //and
                case 2: result = read1 | read2; break; //or
                case 3: result = read1 + read2; break; // add
                case 4: result = read1 - read2; break; // sub
                case 5: result = (read1 < read2)?1:0; break; //slt
                case 6: result = (makeUnsigned(read1) < makeUnsigned(read2)) ? 1 : 0; break; //sltu
                case 7: result = ~(read1 | read2); break; //nor
                case 8: result = (int)read1 << (int)read2; break; //sll
                case 9: result = (int)read1 >> (int)read2; break; //srl
                case 10: zero = (read1 == read2) ? true : false; break;//beq
            }

        
        }

        public ulong makeUnsigned(long number)
        {
            if (number > 0)
                return (ulong)number;

            string bcd = Convert.ToString(number, 2);
            char[] binary = bcd.ToCharArray();
            Array.Reverse(binary);
            ulong result = 0;
            for (int i = 0; i < 32; i++)
            {
                if (binary[i] == '0')
                {
                    continue;
                }
                if (binary[i] == '1')
                {
                    result += Convert.ToUInt64(Math.Pow(2D, (double)i));
                }
            }

            return result;
        }

    }
}
